{{%CONTENT_TYPE:TEXT}}
{{>header}}

@_exported import SotoCore

{{#middlewareFramework}}
import {{ . }}

{{/middlewareFramework}}
/// Service object for interacting with AWS {{name}} service.
{{#first(description)}}
///
{{#description}}
/// {{.}}
{{/description}}
{{/first(description)}}
public struct {{ name }}: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the {{name}} client
    /// - parameters:
    ///     - client: AWSClient used to process requests
{{#regionalized}}
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
{{/regionalized}}
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - timeout: Timeout value for HTTP requests
    public init(
        client: AWSClient,
{{#regionalized}}
        region: SotoCore.Region? = nil,
{{/regionalized}}
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
{{#regionalized}}
            region: region,
            partition: region?.partition ?? partition,
{{/regionalized}}
{{^regionalized}}
            region: nil,
            partition: partition,
{{/regionalized}}
{{#amzTarget}}
            amzTarget: "{{.}}",
{{/amzTarget}}
            service: "{{endpointPrefix}}",
{{#signingName}}
            signingName: "{{.}}",
{{/signingName}}
            serviceProtocol: {{protocol}},
            apiVersion: "{{apiVersion}}",
            endpoint: endpoint,
{{#first(serviceEndpoints)}}
            serviceEndpoints: [{{#serviceEndpoints}}{{.}}{{^last()}}, {{/last()}}{{/serviceEndpoints}}],
{{/first(serviceEndpoints)}}
{{#first(partitionEndpoints)}}
            partitionEndpoints: [{{#partitionEndpoints}}{{.}}{{^last()}}, {{/last()}}{{/partitionEndpoints}}],
{{/first(partitionEndpoints)}}
{{#errorTypes}}
            errorType: {{.}}.self,
{{/errorTypes}}
{{#middlewareClass}}
            middlewares: [{{.}}],
{{/middlewareClass}}
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }

    // MARK: API Calls
{{#operations}}

{{#comment}}
    /// {{.}}
{{/comment}}
{{#documentationUrl}}
    /// {{.}}
{{/documentationUrl}}
{{#deprecated}}
    @available(*, deprecated, message:"{{.}}")
{{/deprecated}}
    {{^outputShape}}@discardableResult {{/outputShape}}public func {{funcName}}({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<{{#outputShape}}{{.}}{{/outputShape}}{{^outputShape}}Void{{/outputShape}}> {
        return self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}, logger: logger, on: eventLoop)
    }
{{/operations}}
{{#first(streamingOperations)}}

    // MARK: Streaming API Calls
{{#streamingOperations}}

{{#comment}}
    /// {{.}}
{{/comment}}
{{#deprecated}}
    @available(*, deprecated, message:"{{.}}")
{{/deprecated}}
    {{^outputShape}}@discardableResult {{/outputShape}}public func {{funcName}}Streaming({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil{{#streaming}}, _ stream: @escaping ({{.}}, EventLoop)->EventLoopFuture<Void>{{/streaming}}) -> EventLoopFuture<{{#outputShape}}{{.}}{{/outputShape}}{{^outputShape}}Void{{/outputShape}}> {
        return self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}, logger: logger, on: eventLoop{{#streaming}}, stream: stream{{/streaming}})
    }
{{/streamingOperations}}
{{/first(streamingOperations)}}
}

extension {{ name }} {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are no public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: {{ name }}, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}
